package spring.cloud.tasks.tasks_manager.tasks_manager.listener;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent.Type;
import spring.cloud.tasks.tasks_manager.tasks_manager.node.Node;
import spring.cloud.tasks.tasks_manager.tasks_manager.service.AllotTaskItemService;
import spring.cloud.tasks.tasks_manager.tasks_manager.service.ExecutorCleanService;

@Slf4j
@Setter
@Getter
public class ExecutorOnlineOfflineListener extends TreeCacheListener {
    private AllotTaskItemService allotTaskItemService;
    private ExecutorCleanService executorCleanService;

    public ExecutorOnlineOfflineListener(AllotTaskItemService allotTaskItemService, ExecutorCleanService executorCleanService) {
        this.allotTaskItemService = allotTaskItemService;
        this.executorCleanService = executorCleanService;
    }

    @Override
    public void childEvent(Type type, String path, String nodeData) throws Exception {
        if (isExecutorOnline(type, path)) {
            String executorId = Node.getExecutorNameByIpPath(path);
            allotTaskItemService.executorOnlineAllotTask(executorId, nodeData);
        } else if (isExecutorOffline(type, path)) {
            String executorId = Node.getExecutorNameByIpPath(path);
            try {
                executorCleanService.clean(executorId);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            try {
                allotTaskItemService.executorOfflineAllotTask(executorId);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    private boolean isExecutorOnline(TreeCacheEvent.Type type, String path) {
        return type == TreeCacheEvent.Type.NODE_ADDED && path.matches(Node.EXECUTOR_IPNODE_PATH_REGEX);
    }

    public boolean isExecutorOffline(TreeCacheEvent.Type type, String path) {
        return type == TreeCacheEvent.Type.NODE_REMOVED && path.matches(Node.EXECUTOR_IPNODE_PATH_REGEX);
    }

}
